﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MemoryGames.Games.Memory
{
	/// <summary>
	/// Interaction logic for Card3D.xaml
	/// </summary>
	public partial class Card3D : UserControl
    {
        #region Properties
        public string CardName { get; set; }
        public int Id { get; set; }
        public int FlipCount { get; set; }
        public CardState State { get; set; }
		public bool Matched { get; set; }
		public bool IsRotating { get; set; }
        #endregion

        #region Events
        public event Action<Card3D> CardClicked;
		public event Action<Card3D> RotationCompleted;
        #endregion

        #region Fields
        private Storyboard _sbRotateCardFront = null;
        private Storyboard _sbRotateCardBack = null;
		private TransformGroup transformGroup;
		private RotateTransform rotateTransform;
		private TranslateTransform translateTransform;
		private Random RANDOM = new Random((int)DateTime.Now.Ticks);
#endregion
        

		public Card3D(int x, int y)
		{
			InitializeComponent();

            //GK Initialize stuff
            _sbRotateCardFront = (Storyboard)this.FindResource("SbRotateCardFront");
            _sbRotateCardBack = (Storyboard)this.FindResource("SbRotateCardBack");

            //GK Add completed handler so we know when the card has been finished rotating
			_sbRotateCardFront.Completed += new EventHandler(HandleRotationCompleted);

			// Initialize and add transformations
			transformGroup = new TransformGroup();
			rotateTransform = new RotateTransform();
			translateTransform = new TranslateTransform(x, y);
			transformGroup.Children.Add(rotateTransform);
			transformGroup.Children.Add(translateTransform);
			this.RenderTransform = transformGroup;
		}

		private void UserControl_MouseUp(object sender, MouseButtonEventArgs e)
		{
            //GK Raise card clicked event
            if (CardClicked != null) CardClicked(this);
		}

        public void RotateCard()
        {
            //GK Skip event while the card is rotating
            if (IsRotating) return;

            switch (State)
            {
                case CardState.Closed:
                    State = CardState.Open;
                    FlipCount++;
                    Rotate();
                    break;
                case CardState.Open:
                    State = CardState.Closed;
                    Rotate();
                    break;
            }
        }

		private void Rotate()
		{
            IsRotating = true;

            _sbRotateCardBack.Begin();
            _sbRotateCardFront.Begin();
		}

		/// <summary>
		/// Applies a glow effect animation to the cards
		/// </summary>
		/// <param name="delay">Delays the effect for the given milliseconds</param>
		public void PutOnStack(int delay)
		{
			// Apply a glow effect
			//Rectangle rect = new Rectangle();
			//rect.Width = this.Width;
			//rect.Height = this.Height;
			//rect.Fill = Brushes.White;
			//rect.Stretch = Stretch.Fill;
			//rect.Opacity = 0;
			//this.CardFrontSidePanel.Children.Add(rect);
			
			//DoubleAnimation glowAnimation = new DoubleAnimation(0.0, 0.75, new Duration(TimeSpan.FromMilliseconds(200)));
			//glowAnimation.RepeatBehavior = new RepeatBehavior(1);
			//glowAnimation.AutoReverse = true;
			//glowAnimation.BeginTime = TimeSpan.FromMilliseconds(delay);
			//rect.BeginAnimation(Rectangle.OpacityProperty, glowAnimation);

			// Add a small random rotation so it will be not placed perfectly on the stack
			double randomRotation = RANDOM.Next(200)/10.0 - 10.0;
			DoubleAnimation moveAnimationX = new DoubleAnimation(translateTransform.X, 800, new Duration(TimeSpan.FromMilliseconds(1000)));
			DoubleAnimation moveAnimationY = new DoubleAnimation(translateTransform.Y, 400, new Duration(TimeSpan.FromMilliseconds(1000)));
			DoubleAnimation rotateAnimation = new DoubleAnimation(0, 360*2 + randomRotation, new Duration(TimeSpan.FromMilliseconds(1000)));

			moveAnimationX.AccelerationRatio = 1.0;
			moveAnimationY.AccelerationRatio = 1.0;

			moveAnimationX.BeginTime = TimeSpan.FromMilliseconds(delay);
			moveAnimationY.BeginTime = TimeSpan.FromMilliseconds(delay);

			rotateTransform.CenterX = this.Width / 2;
			rotateTransform.CenterY = this.Height / 2;

			rotateTransform.BeginAnimation(RotateTransform.AngleProperty, rotateAnimation);
			translateTransform.BeginAnimation(TranslateTransform.XProperty, moveAnimationX);
			translateTransform.BeginAnimation(TranslateTransform.YProperty, moveAnimationY);
		}

		private void HandleRotationCompleted(object sender, EventArgs e)
        {
            IsRotating = false;

			//GK Raise rotation completed event
			if (RotationCompleted != null) RotationCompleted(this);
        }
	}

	public enum CardState
	{
		Closed,
		Open,
		Matched,
		Hidden,
		Locked
	}
}
